#include "manifest.h"
#include "slib.h"
#include <jni.h>

jstring Java_com_googlecode_droidjni_droid_logTag(JNIEnv* env, jobject this) {
    return (*env)->NewStringUTF(env, LOG_TAG);
}

jint Java_com_googlecode_droidjni_droid_add(JNIEnv* env, jobject this, jint x, jint y) {
    return slib_add(x, y);
}

void Java_com_googlecode_droidjni_droid_nop(JNIEnv* env, jobject this) {
}

static int count;

static __attribute__((noinline)) void noinline() { // best seen ~12 nanoseconds per call
    count++;
}

static char buf0[1024];
static char buf1[1024];

static void timing() {
    void (*foo)() = noinline; // to prevent inlining
    count = 0;
    timestamp("1,000,000 native calls");
    for (int i = 0; i < 100000; i++) {
        foo(); foo(); foo(); foo(); foo();
        foo(); foo(); foo(); foo(); foo();
    }
    timestamp("1,000,000 native calls");
    assert(count == 1000000);

    assert(sizeof(buf0) == sizeof(buf1));
    count = 0;
    timestamp("1,024 x 1,024 x 1KB memcpy");
    for (int i = 0; i < 1024 * 1024; i++) {
        buf1[sizeof(buf1) - 1] = (char)(count & 0xFF);
        memcpy(buf0, buf1, sizeof(buf0)); // ~330 mks
        assertion(buf1[sizeof(buf1) - 1] == buf0[sizeof(buf0) - 1],
                  "expected 0x%02X found 0x%02X",
                  buf1[sizeof(buf1)], buf0[sizeof(buf0)]);
        count++;
    }
    timestamp("1,024 x 1,024 x 1KB memcpy");
    /* best time seen ~355 milliseconds */
    assert(count == 1024 * 1024);

    timestamp("empty trace");
    trace(""); /* best time seen ~90 microseconds */
    timestamp("empty trace");
}


void Java_com_googlecode_droidjni_droid_smokeTests(JNIEnv* env, jobject this) {
/*  timing(); */
    mapsl_smoke_test(true);
    mapll_smoke_test(true);
    queue_smoke_test();
    ashmem_smoke_test();
    futex_smoke_test();
    sem_smoke_test();
    mutex_smoke_test();
}

